package org.jsola.hr.common;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.row.SimpleRowHeightStyleStrategy;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.jsola.common.*;
import org.jsola.exception.ParamException;
import org.jsola.hr.exception.HrException;
import org.jsola.hr.query.ExportColumn;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zhr
 */
@Slf4j
public class ExcelKit {

    private static final String DATE_FORMAT = "yyyyMMddHHmmss";

    /**
     * 合计行数据
     */
    @Data
    static class TotalHeadData {
        /**
         * 表头
         */
        private String head;

        /**
         * 下标
         */
        private Integer index;

        /**
         * 数据
         */
        private String value;
    }

    /**
     * 要导出的数据
     */
    @Data
    static class ExportData {
        /**
         * 时间类型格式
         */
        private String dateFormat;

        /**
         * 列名代码
         */
        private String dataIndex;
    }

    /**
     * 导出的excel并返回文件路径
     *
     * @param enName    英文名，用于模版路径 英文名 + Template.xlsx
     * @param name      中文名，用于sheet名称和错误提示
     * @param headClass excel标题列的类
     * @param dataList  数据
     * @return excel的文件路径
     */
    public static String exportExcel(String enName, String name, Class<?> headClass, List<?> dataList) {
        // 模板文件
        InputStream is = ExcelKit.class.getClassLoader().getResourceAsStream("excel/" + enName + "ExportTemplate.xlsx");
        HrException.notNull(is, name + "模板没有找到");
        // 创建需要导出的文件
        String tempFilePath = FileKit.getSystemTempPath();
        boolean flg = new File(tempFilePath).mkdir();
        String fileName = name + DateKit8.format(new Date(), DATE_FORMAT) + ".xlsx";
        tempFilePath += fileName;
        File excelFile = new File(tempFilePath);
        try {
            if (!excelFile.exists()) {
                flg = new File(tempFilePath).createNewFile();
            }
        } catch (IOException e) {
            log.error("创建excel文件失败", e);
            throw new HrException("创建excel文件失败" + e.getMessage());
        }
        ExcelWriter excelWriter = EasyExcel.write(tempFilePath, headClass).withTemplate(is).build();
        WriteSheet writeSheet = EasyExcel.writerSheet().build();
        ParamException.notEmpty(dataList, "没有需要导出的数据，请调整检索条件");
        // 用填充的方式写入数据
        excelWriter.fill(dataList, writeSheet);
        // 关闭流
        excelWriter.finish();
        HrException.isTrue(excelFile.exists(), "导出失败，没有生成导出文件");
        return tempFilePath;
    }


    public static String exportExcelHeader(String enName, String name, List<List<String>> headList) {
        // 模板文件
        InputStream is = ExcelKit.class.getClassLoader().getResourceAsStream("excel/" + enName + "ExportTemplate.xlsx");
        HrException.notNull(is, name + "模板没有找到");
        // 创建需要导出的文件
        String tempFilePath = FileKit.getSystemTempPath();
        boolean flg = new File(tempFilePath).mkdir();
        String fileName = name + DateKit8.format(new Date(), DATE_FORMAT) + ".xlsx";
        tempFilePath += fileName;
        File excelFile = new File(tempFilePath);
        try {
            if (!excelFile.exists()) {
                flg = new File(tempFilePath).createNewFile();
            }
        } catch (IOException e) {
            log.error("创建excel文件失败", e);
            throw new HrException("创建excel文件失败" + e.getMessage());
        }
        ExcelWriter excelWriter = EasyExcel.write(tempFilePath).head(headList).withTemplate(is).build();
        WriteSheet writeSheet = EasyExcel.writerSheet(name).build();
        // 关闭流
        excelWriter.write(new ArrayList(), writeSheet);
        excelWriter.finish();
        HrException.isTrue(excelFile.exists(), "导出失败，没有生成导出文件");
        return tempFilePath;
    }


    public static String exportExcelDynamic(String enName, String name, List<List<String>> dataList, List<List<String>> headList) {
        // 模板文件
        InputStream is = ExcelKit.class.getClassLoader().getResourceAsStream("excel/" + enName + "ExportTemplate.xlsx");
        HrException.notNull(is, name + "模板没有找到");
        // 创建需要导出的文件
        String tempFilePath = FileKit.getSystemTempPath();
        boolean flg = new File(tempFilePath).mkdir();
        String fileName = name + DateKit8.format(new Date(), DATE_FORMAT) + ".xlsx";
        tempFilePath += fileName;
        File excelFile = new File(tempFilePath);
        try {
            if (!excelFile.exists()) {
                flg = new File(tempFilePath).createNewFile();
            }
        } catch (IOException e) {
            log.error("创建excel文件失败", e);
            throw new HrException("创建excel文件失败" + e.getMessage());
        }

        // 头和内容的策略
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = generalTactics(false);


        ExcelWriter excelWriter = EasyExcel.write(tempFilePath).head(headList).withTemplate(is).build();
        WriteSheet writeSheet = EasyExcel.writerSheet(name)
                .registerWriteHandler(new FreezeAndFilter())
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 30, null))
                .registerWriteHandler(new CustomCellWriteHandler())
                .registerWriteHandler(horizontalCellStyleStrategy).build();
        ParamException.notEmpty(dataList, "没有需要导出的数据，请调整检索条件");
        // 用填充的方式写入数据
        excelWriter.write(dataList, writeSheet);

        // 关闭流
        excelWriter.finish();
        HrException.isTrue(excelFile.exists(), "导出失败，没有生成导出文件");
        return tempFilePath;
    }

    /**
     * @param name     文件名
     * @param dataList 数据集合
     * @param headList 表头集合
     * @return
     */
    public static String exportExcelDynamic(String name, List<List<String>> headList, List<List<String>> dataList) {
        // 创建需要导出的文件
        String tempFilePath = FileKit.getSystemTempPath();
        boolean flg = new File(tempFilePath).mkdir();
        String fileName = name + DateKit8.format(new Date(), DATE_FORMAT) + ".xlsx";
        tempFilePath += fileName;
        File excelFile = new File(tempFilePath);
        try {
            if (!excelFile.exists()) {
                flg = new File(tempFilePath).createNewFile();
            }
        } catch (IOException e) {
            log.error("创建excel文件失败", e);
            throw new HrException("创建excel文件失败" + e.getMessage());
        }

        // 头和内容的策略
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = generalTactics(false);

        // 默认表头只有一行
        TotalRowHandler totalRowHandler = new TotalRowHandler(dataList.size());
        ExcelWriterSheetBuilder excelWriterSheetBuilder = EasyExcel.write(tempFilePath).head(headList).sheet("供应商")
                .registerWriteHandler(new FreezeAndFilter())
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 30, null))
                .registerWriteHandler(new CustomCellWriteHandler())
                .registerWriteHandler(horizontalCellStyleStrategy)
                .registerWriteHandler(totalRowHandler);
        excelWriterSheetBuilder.doWrite(dataList);

        HrException.isTrue(excelFile.exists(), "导出失败，没有生成导出文件");
        return tempFilePath;
    }

    /**
     * 自定义列导出excel
     * 如果某个导出字段是Date类型处理为yyyy-MM-dd格式
     * 如果某个导出字段是Boolean类型处理为 "已处理" "未处理"
     *
     * @param name              写出文件名称
     * @param exportColumns     导出的列对象集合
     * @param dataList          数据对象列表
     * @param onlyHead          仅导出表头
     * @param sheetName         sheetName
     * @param cellWriteHandlers 样式处理类
     */
    public static String writeCustomizeExcelWithModel(String name, List<ExportColumn> exportColumns, List<?> dataList,
                                                      Boolean onlyHead, String sheetName, CellWriteHandler... cellWriteHandlers) {
        // 表头为中文名，所以需要再定义一个英文名的集合，准备反射获取属性
        List<List<String>> headList = new ArrayList<>();
        // 表头英文名集合
        List<ExportData> headPropertyList = new ArrayList<>();
        // 数据集合
        List<List<String>> dataListItem = new ArrayList<>();
        ParamException.notEmpty(exportColumns, "导出列不能为空");

        for (ExportColumn exportColumn : exportColumns) {
            List<String> head = new ArrayList<>();
            // 表头 例：姓名
            head.add(exportColumn.getTitle());
            headList.add(head);
            // 英文字段 例：name
            ExportData exportData = new ExportData();
            exportData.setDataIndex(exportColumn.getDataIndex());
            exportData.setDateFormat(exportColumn.getDateFormat());
            headPropertyList.add(exportData);
        }
        for (Object data : dataList) {
            // 定义每一条数据
            List<String> oneData = new ArrayList<>();
            for (ExportData exportData : headPropertyList) {
                String property = exportData.getDataIndex();
                String value = null;
                try {
                    Object object = ClassKit.getValue(data, property);
                    log.debug("自定义列导出=====》字段：property：{},   类型：{}", property, object.getClass());
                    // 如果是Date类型设置为yyyy-MM-dd
                    if (object instanceof Date) {
                        if (StrKit.isNotEmpty(exportData.getDateFormat())) {
                            value = DateKit8.format((Date) object, exportData.getDateFormat());
                        } else {
                            value = DateKit8.format2Date((Date) object);
                        }
                    } else if ((object instanceof Boolean)) {
                        if (StrKit.isEmpty(SafeKit.getString(object))) {
                            value = "";
                        } else {
                            value = "false".equals(SafeKit.getString(object)) ? "未处理" : "已处理";
                        }
                    } else {
                        value = SafeKit.getString(object);
                    }
                } catch (Exception e) {
                    log.error("字段转换错误：property：{}", property);
                }
                oneData.add(value);
            }
            dataListItem.add(oneData);
        }
        return ExcelKit.writeExcelWithModel(name, dataListItem, headList, onlyHead, sheetName, cellWriteHandlers);
    }

    /**
     * 导出excel
     *
     * @param name              写出文件名称
     * @param dataList          导出的数据
     * @param onlyHead          仅导出表头
     * @param sheetName         sheetName
     * @param cellWriteHandlers 样式处理类
     */
    public static String writeExcelWithModel(String name, List<? extends Object> dataList
            , List<List<String>> headList, Boolean onlyHead, String sheetName, CellWriteHandler... cellWriteHandlers) {
        if (!onlyHead) {
            ParamException.notEmpty(dataList, "没有需要导出的数据，请调整检索条件");
        } else {
            dataList = new ArrayList<>();
        }
        // 创建需要导出的文件
        String tempFilePath = FileKit.getSystemTempPath();
        String fileName = name + DateKit8.format(new Date(), DATE_FORMAT) + ".xlsx";
        boolean mkdir = new File(tempFilePath).mkdir();
        tempFilePath += fileName;
        File file = new File(tempFilePath);
        // 头和内容的策略
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = generalTactics(false);

        ExcelWriterSheetBuilder excelWriterSheetBuilder = EasyExcel.write(tempFilePath).head(headList).sheet(sheetName)
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 30, null))
                .registerWriteHandler(horizontalCellStyleStrategy);
        if (null != cellWriteHandlers && cellWriteHandlers.length > 0) {
            for (CellWriteHandler cellWriteHandler : cellWriteHandlers) {
                excelWriterSheetBuilder.registerWriteHandler(cellWriteHandler);
            }
        }
        excelWriterSheetBuilder.registerWriteHandler(new CustomCellWriteHandler());
        excelWriterSheetBuilder.doWrite(dataList);
        return tempFilePath;
    }

    public static String complexExportExcel(String enName, String name, List<List<String>> headList, List<?> dataList, Map<String, Object> map) {
        // 模板文件
        InputStream is = ExcelKit.class.getClassLoader().getResourceAsStream("excel/" + enName + "ExportTemplate.xlsx");
        HrException.notNull(is, name + "模板没有找到");
        // 创建需要导出的文件
        String tempFilePath = FileKit.getSystemTempPath();
        boolean flg = new File(tempFilePath).mkdir();
        String fileName = name + DateKit8.format(new Date(), DATE_FORMAT) + ".xlsx";
        tempFilePath += fileName;
        File excelFile = new File(tempFilePath);
        try {
            if (!excelFile.exists()) {
                flg = new File(tempFilePath).createNewFile();
            }
        } catch (IOException e) {
            log.error("创建excel文件失败", e);
            throw new HrException("创建excel文件失败" + e.getMessage());
        }
        ExcelWriter excelWriter = EasyExcel.write(tempFilePath).withTemplate(is).build();
        WriteSheet writeSheet = EasyExcel.writerSheet(name).build();
        ParamException.notEmpty(dataList, "没有需要导出的数据，请调整检索条件");
        // 用填充的方式写入数据
        excelWriter.fill(map, writeSheet);
        // 用填充的方式写入数据
        excelWriter.write(headList, writeSheet);
        excelWriter.write(dataList, writeSheet);
        // 关闭流
        excelWriter.finish();
        HrException.isTrue(excelFile.exists(), "导出失败，没有生成导出文件");
        return tempFilePath;
    }

    /**
     * 导出带有合计的动态表头（合计行会添加样式）
     *
     * @param enName       导出excel模板名称
     * @param name         excel文件名称
     * @param dataList     数据
     * @param headList     表头
     * @param totalHeadSet 合计列表头
     * @return excel地址
     */
    public static String exportExcelDynamicAndTotal(String enName, String name, List<List<String>> dataList, List<List<String>> headList,
                                                    HashSet<String> totalHeadSet) {
        // 模板文件
        InputStream is = ExcelKit.class.getClassLoader().getResourceAsStream("excel/" + enName + "ExportTemplate.xlsx");
        HrException.notNull(is, name + "模板没有找到");
        // 创建需要导出的文件
        String tempFilePath = FileKit.getSystemTempPath();
        boolean flg = new File(tempFilePath).mkdir();
        String fileName = name + DateKit8.format(new Date(), DATE_FORMAT) + ".xlsx";
        tempFilePath += fileName;
        File excelFile = new File(tempFilePath);
        try {
            if (!excelFile.exists()) {
                flg = new File(tempFilePath).createNewFile();
            }
        } catch (IOException e) {
            log.error("创建excel文件失败：", e);
            throw new HrException("创建excel文件失败：" + e.getMessage());
        }
        ParamException.notEmpty(dataList, "没有需要导出的数据，请调整检索条件");
        ExcelWriter excelWriter = EasyExcel.write(tempFilePath).head(headList).withTemplate(is).build();

        // 头和内容的策略
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = generalTactics(false);

        // 默认表头只有一行
        TotalRowHandler totalRowHandler = new TotalRowHandler(dataList.size());
        WriteSheet writeSheet = EasyExcel.writerSheet()
                .registerWriteHandler(new FreezeAndFilter())
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 30, null))
                .registerWriteHandler(new CustomCellWriteHandler())
                .registerWriteHandler(horizontalCellStyleStrategy)
                .registerWriteHandler(totalRowHandler)
                .build();
        addTotalRow(headList, dataList, totalHeadSet);
        // 用填充的方式写入数据
        excelWriter.write(dataList, writeSheet);

        // 关闭流
        excelWriter.finish();
        HrException.isTrue(excelFile.exists(), "导出失败，没有生成导出文件");
        return tempFilePath;
    }

    /**
     * 导出的excel并返回文件路径(自定义合并单元格)
     */
    public static String exportExcelMerge(String enName, String name, Class<?> headClass, List<?> dataList,
                                          int mergeRowIndex, int[] mergeColumnIndex) {
        // 模板文件
        InputStream is = ExcelKit.class.getClassLoader().getResourceAsStream("excel/" + enName + "ExportTemplate.xlsx");
        HrException.notNull(is, name + "模板没有找到");
        // 创建需要导出的文件
        String tempFilePath = FileKit.getSystemTempPath();
        boolean flg = new File(tempFilePath).mkdir();
        String fileName = name + DateKit8.format(new Date(), DATE_FORMAT) + ".xlsx";
        tempFilePath += fileName;
        File excelFile = new File(tempFilePath);
        try {
            if (!excelFile.exists()) {
                flg = new File(tempFilePath).createNewFile();
            }
        } catch (IOException e) {
            log.error("创建excel文件失败", e);
            throw new HrException("创建excel文件失败" + e.getMessage());
        }
        ExcelWriter excelWriter = EasyExcel.write(tempFilePath, headClass).withTemplate(is)
                .registerWriteHandler(new ExcelMergeUtil(mergeRowIndex, mergeColumnIndex)).build();
        WriteSheet writeSheet = EasyExcel.writerSheet().build();
        ParamException.notEmpty(dataList, "没有需要导出的数据，请调整检索条件");
        // 用填充的方式写入数据
        excelWriter.write(dataList, writeSheet);
        // 关闭流
        excelWriter.finish();
        HrException.isTrue(excelFile.exists(), "导出失败，没有生成导出文件");
        return tempFilePath;
    }

    /**
     * 写入合计行,直接写入导出数据里，数据为空不会写入
     * 先找出所有需要进行合计的列，遍历这一列的数据，进行累加操作，最后将计算出的合计写入到最后一行
     *
     * @param headList     表头
     * @param dataList     数据
     * @param totalHeadSet 需要合计的列表头名称
     */
    private static void addTotalRow(List<List<String>> headList, List<List<String>> dataList, HashSet<String> totalHeadSet) {
        if (!CollectionUtils.isEmpty(totalHeadSet)) {
            // 需要合计的列，表头和列下标
            List<TotalHeadData> headIndexData = new ArrayList<>();
            for (int i = 0; i < headList.size(); i++) {
                // i是表头的列下标
                List<String> stringList = headList.get(i);
                String head = stringList.get(0);
                // 需要合计的表头
                if (totalHeadSet.contains(head)) {
                    TotalHeadData headData = new TotalHeadData();
                    headData.setHead(head);
                    headData.setIndex(i);
                    headIndexData.add(headData);
                }
            }
            // 下标-数据对象
            Map<Integer, TotalHeadData> indexTotalHeadData = headIndexData
                    .parallelStream()
                    .collect(Collectors.toMap(TotalHeadData::getIndex, v -> v));
            // 遍历行
            for (List<String> rowList : dataList) {
                // 遍历列
                for (int i = 0; i < rowList.size(); i++) {
                    if (indexTotalHeadData.containsKey(i)) {
                        TotalHeadData totalHeadData = indexTotalHeadData.get(i);
                        // 累计数据
                        String valueTotal = totalHeadData.getValue();
                        BigDecimal total = BigDecimal.ZERO;
                        if (StrKit.isNotEmpty(valueTotal)) {
                            try {
                                total = new BigDecimal(valueTotal);
                            } catch (Exception e) {
                                log.error("String转换BigDecimal失败，累计值：{}，错误信息：{}", valueTotal, e.getMessage());
                            }
                        }
                        // 本次数据
                        String valueNow = rowList.get(i);
                        BigDecimal decimalNow = BigDecimal.ZERO;
                        if (StrKit.isNotEmpty(valueNow)) {
                            try {
                                decimalNow = new BigDecimal(valueNow);
                            } catch (Exception e) {
                                log.error("String转换BigDecimal失败，单元格内容：{}，错误信息：{}", valueNow, e.getMessage());
                            }
                        }
                        total = total.add(decimalNow);
                        totalHeadData.setValue(String.valueOf(total));
                    }
                }
            }
            // 写入合计行
            List<String> totalRow = Arrays.asList(new String[headList.size()]);

            // 修改行数据
            for (int i = 0; i < totalRow.size(); i++) {
                if (indexTotalHeadData.containsKey(i)) {
                    TotalHeadData totalHeadData = indexTotalHeadData.get(i);
                    totalRow.set(i, totalHeadData.getValue());
                }
            }
            dataList.add(totalRow);
        }
    }

    /**
     * 导出excel(可以设置头和单元格的样式)
     *
     * @param name                  写出文件名称
     * @param dataList              导出的数据
     * @param onlyHead              仅导出表头
     * @param headWriteCellStyle    头的策略
     * @param contentWriteCellStyle 单元格策略
     * @param sheetName             sheetName
     * @param cellWriteHandlers     样式处理类
     */
    public static String writeExcelWithModel(String name, List<? extends Object> dataList,
                                             List<List<String>> headList, Boolean onlyHead,
                                             WriteCellStyle headWriteCellStyle, WriteCellStyle contentWriteCellStyle,
                                             String sheetName, CellWriteHandler... cellWriteHandlers) {
        if (!onlyHead) {
            ParamException.notEmpty(dataList, "没有需要导出的数据，请调整检索条件");
        } else {
            dataList = new ArrayList<>();
        }
        // 创建需要导出的文件
        String tempFilePath = FileKit.getSystemTempPath();
        String fileName = name + DateKit8.format(new Date(), DATE_FORMAT) + ".xlsx";
        boolean mkdir = new File(tempFilePath).mkdir();
        tempFilePath += fileName;
        File file = new File(tempFilePath);
        // 头的策略
        if (headWriteCellStyle == null) {
            headWriteCellStyle = new WriteCellStyle();
        }
        // 单元格策略
        if (contentWriteCellStyle == null) {
            contentWriteCellStyle = new WriteCellStyle();
        }
        // 初始化表格样式
        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

        ExcelWriterSheetBuilder excelWriterSheetBuilder = EasyExcel.write(tempFilePath).head(headList).sheet(sheetName)
                .registerWriteHandler(horizontalCellStyleStrategy);
        if (null != cellWriteHandlers && cellWriteHandlers.length > 0) {
            for (CellWriteHandler cellWriteHandler : cellWriteHandlers) {
                excelWriterSheetBuilder.registerWriteHandler(cellWriteHandler);
            }
        }
        excelWriterSheetBuilder.doWrite(dataList);
        return tempFilePath;
    }

    public static String writeExcelTotalAndNotTemplate(String name, List<List<String>> dataList,
                                                       List<List<String>> headList,
                                                       String sheetName, HashSet<String> totalHeadSet) {
        // 创建需要导出的文件
        String tempFilePath = FileKit.getSystemTempPath();
        String fileName = name + DateKit8.format(new Date(), DATE_FORMAT) + ".xlsx";
        boolean mkdir = new File(tempFilePath).mkdir();
        tempFilePath += fileName;
        File file = new File(tempFilePath);
        // 头和内容的策略
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = generalTactics(true);
        // 默认表头只有一行
        TotalRowHandler totalRowHandler = new TotalRowHandler(dataList.size());
        ExcelWriterSheetBuilder excelWriterSheetBuilder = EasyExcel.write(tempFilePath).head(headList).sheet(sheetName)
                .registerWriteHandler(new FreezeAndFilter())
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 30, null))
                .registerWriteHandler(new CustomCellWriteHandler())
                .registerWriteHandler(horizontalCellStyleStrategy)
                .registerWriteHandler(totalRowHandler);
        addTotalRow(headList, dataList, totalHeadSet);
        excelWriterSheetBuilder.doWrite(dataList);
        return tempFilePath;
    }

    public static String exportExcelNotTemplate(String name, List<List<String>> dataList, List<List<String>> headList,
                                                String sheetName) {
        // 创建需要导出的文件
        String tempFilePath = FileKit.getSystemTempPath();
        String fileName = name + DateKit8.format(new Date(), DATE_FORMAT) + ".xlsx";
        boolean mkdir = new File(tempFilePath).mkdir();
        tempFilePath += fileName;
        File file = new File(tempFilePath);
        // 头和内容的策略
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = generalTactics(true);
        ExcelWriterSheetBuilder excelWriterSheetBuilder = EasyExcel.write(tempFilePath).head(headList).sheet(sheetName)
                .registerWriteHandler(new FreezeAndFilter())
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 30, null))
                .registerWriteHandler(new CustomCellWriteHandler())
                .registerWriteHandler(horizontalCellStyleStrategy);
        excelWriterSheetBuilder.doWrite(dataList);
        return tempFilePath;
    }

    public static String exportExcelNotTemplate2(String name, List<List<String>> dataList, List<List<String>> headList,
                                                 String sheetName) {
        // 创建需要导出的文件
        String tempFilePath = FileKit.getSystemTempPath();
        String fileName = name + DateKit8.format(new Date(), DATE_FORMAT) + ".xlsx";
        boolean mkdir = new File(tempFilePath).mkdir();
        tempFilePath += fileName;
        File file = new File(tempFilePath);
        // 头和内容的策略
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = generalTactics(true);
        ExcelWriterSheetBuilder excelWriterSheetBuilder = EasyExcel.write(tempFilePath).head(headList).sheet(sheetName)
                .registerWriteHandler(new FreezeAndFilter())
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 30, null))
                .registerWriteHandler(horizontalCellStyleStrategy);
        excelWriterSheetBuilder.doWrite(dataList);
        return tempFilePath;
    }


    /**
     * @param name
     * @param headList         表头List
     * @param sheetName
     * @param dataList         数据List
     * @param styleList        自定义行高
     * @param cellWriteHandler
     * @return
     */
    public static String generateExcel(String name, List<List<String>> headList, String sheetName
            , List<List<String>> dataList, List<CellRowHeightStyleStrategy.Style> styleList, CellWriteHandler cellWriteHandler) {
        // 创建需要导出的文件
        String tempFilePath = FileKit.getSystemTempPath();
        String fileName = name + DateKit8.format(new Date(), DATE_FORMAT) + ".xlsx";
        boolean mkdir = new File(tempFilePath).mkdir();
        tempFilePath += fileName;
        File file = new File(tempFilePath);
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = generalTactics(false);
        ExcelWriterSheetBuilder builder = EasyExcel.write(tempFilePath).head(headList).sheet(sheetName)
                .registerWriteHandler(new AdaptiveColumnWidthStrategy());
        if (!CollectionUtils.isEmpty(styleList)) {
            builder.registerWriteHandler(new CellRowHeightStyleStrategy(styleList));
        }
        builder.registerWriteHandler(horizontalCellStyleStrategy);
        // 标红,下拉,批注
        if (!ObjectUtils.isEmpty(cellWriteHandler)) {
            builder.registerWriteHandler(cellWriteHandler);
        }
        builder.doWrite(dataList);
        return tempFilePath;
    }

    /**
     * 通用内容和头策略
     */
    public static HorizontalCellStyleStrategy generalTactics(Boolean center) {
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景设置为蓝色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());
        //字体
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 11);
        headWriteFont.setBold(true);
        headWriteCellStyle.setWriteFont(headWriteFont);
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        if (center) {
            contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        }
        return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
    }
}
